package com.lyf.scm.plan.domain.remote.basedata.facade;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.lyf.scm.common.constants.CommonConstants;
import com.lyf.scm.common.enums.ResponseMsg;
import com.lyf.scm.common.model.SalesPlanSelectDTO;
import com.lyf.scm.plan.api.dto.StoreInfoDTO;
import com.lyf.scm.plan.domain.remote.basedata.BaseDataRemote;
import com.lyf.scm.plan.domain.remote.basedata.dto.*;
import com.rome.arch.core.clientobject.Response;
import com.rome.arch.core.exception.RomeException;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 基本数据外观
 *
 * @author wuzhuang
 * @date 2020/06/30
 */
@Slf4j
@Service
public class BaseDataFacade {

    @Resource
    private BaseDataRemote baseDataRemote;

    /**
     * 获取省份信息
     *
     * @param provinceList
     * @return
     */
    public List<AreaDTO> listProvinceByList(List<String> provinceList) {
        List<AreaDTO> areaList = new ArrayList<>();
        provinceList.forEach(item -> {
            Response<List<AreaDTO>> response = baseDataRemote.listAreaInfoByName(item);
            if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
                throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
            }
            areaList.add(response.getData().get(0));
        });
        return areaList;
    }


    /**
     * 根据code获取区域信息
     *
     * @param codes
     * @return
     */
    public List<AreaDTO> listAreaInfoByCode(List<String> codes) {
        Response<List<AreaDTO>> response = baseDataRemote.listAreaInfoByCode(codes);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }


    /**
     * 根据父区域获取下级区域
     *
     * @param areaCodeList
     * @return
     */
    public List<SalesPlanSelectDTO> getSubAreaCode(List<SalesPlanSelectDTO> areaCodeList) {
        log.info("根据父区域获取下级区域：areaCodeList：{}", areaCodeList);
        if (CollectionUtils.isEmpty(areaCodeList)) {
            return null;
        }
        //对参数集合进行分组，分组后如果size为1，直接返回
        Map<Integer, List<SalesPlanSelectDTO>> listMap = areaCodeList.stream().collect(Collectors.groupingBy(SalesPlanSelectDTO::getLevel));
        final int reqSize = 1;
        //map长度大于1表示该查询条件携带层级不同的参数，区域有四层level；
        if (listMap.size() > reqSize) {
            // 获取最低级level值
            int subLevel = areaCodeList.stream().mapToInt(SalesPlanSelectDTO::getLevel).max().getAsInt();
            // 获取level最低的对象集
            List<SalesPlanSelectDTO> leafCodeList = areaCodeList.stream().filter(item -> item.getLevel().equals(subLevel)).collect(Collectors.toList());
            List<String> paramList = new ArrayList<>();
            //如果存在门店->即第四级区域
            if (CollectionUtil.isNotEmpty(listMap.get(CommonConstants.AREA_LEVEL_FOUR))) {
                return this.getStoreLevel(leafCodeList, paramList, listMap);
            }
            //如果存在区->即第三级区域
            if (CollectionUtil.isNotEmpty(listMap.get(CommonConstants.AREA_LEVEL_THREE))) {
                if (ObjectUtil.isNotEmpty(listMap.get(CommonConstants.AREA_LEVEL_ONE))) {
                    listMap.get(CommonConstants.AREA_LEVEL_ONE).forEach(item -> paramList.add(item.getCode()));
                    List<AreaDTO> cityCode = this.batchSearchByParentCode(paramList);
                    paramList.clear();
                    if (ObjectUtil.isNotEmpty(cityCode)) {
                        cityCode.forEach(item -> {
                            paramList.add(item.getCode());
                        });
                    }
                }
                if (ObjectUtil.isNotEmpty(listMap.get(CommonConstants.AREA_LEVEL_TWO))) {
                    listMap.get(CommonConstants.AREA_LEVEL_TWO).forEach(item -> paramList.add(item.getCode()));
                    return this.dealOtherLevel(leafCodeList, paramList);
                } else {
                    //根据二级区域获取第三级区域
                    return this.dealOtherLevel(leafCodeList, paramList);
                }
            }
            //如果存在市->即第二级区域
            if (ObjectUtil.isNotEmpty(listMap.get(CommonConstants.AREA_LEVEL_TWO))) {
                if (ObjectUtil.isNotEmpty(listMap.get(CommonConstants.AREA_LEVEL_ONE))) {
                    listMap.get(CommonConstants.AREA_LEVEL_ONE).forEach(item -> paramList.add(item.getCode()));
                    return this.dealOtherLevel(leafCodeList, paramList);
                }
            }
        }
        return areaCodeList;
    }

    /**
     * 处理有门店级别的区域类型
     */
    public List<SalesPlanSelectDTO> getStoreLevel(List<SalesPlanSelectDTO> leafCodeList, List<String> paramList, Map<Integer, List<SalesPlanSelectDTO>> listMap) {
        List<StoreDTO> storeList = new ArrayList<>();
        if (ObjectUtil.isNotEmpty(listMap.get(CommonConstants.AREA_LEVEL_ONE))) {
            listMap.get(CommonConstants.AREA_LEVEL_ONE).forEach(item -> paramList.add(item.getCode()));
            storeList.addAll(this.ListStoreByArea(paramList, CommonConstants.AREA_LEVEL_ONE, 1, 3000));
        }
        if (ObjectUtil.isNotEmpty(listMap.get(CommonConstants.AREA_LEVEL_TWO))) {
            listMap.get(CommonConstants.AREA_LEVEL_TWO).forEach(item -> paramList.add(item.getCode()));
            storeList.addAll(this.ListStoreByArea(paramList, CommonConstants.AREA_LEVEL_ONE, 1, 3000));
        }
        if (ObjectUtil.isNotEmpty(listMap.get(CommonConstants.AREA_LEVEL_THREE))) {
            listMap.get(CommonConstants.AREA_LEVEL_THREE).forEach(item -> paramList.add(item.getCode()));
            storeList.addAll(this.ListStoreByArea(paramList, CommonConstants.AREA_LEVEL_ONE, 1, 3000));
        }
        storeList.forEach(store -> {
            SalesPlanSelectDTO salesPlanSelect = new SalesPlanSelectDTO();
            salesPlanSelect.setCode(store.getCode());
            salesPlanSelect.setLevel(CommonConstants.AREA_LEVEL_FOUR);
            leafCodeList.add(salesPlanSelect);
        });
        return leafCodeList.stream().distinct().collect(Collectors.toList());
    }

    public List<AreaDTO> batchSearchByParentCode(List<String> parentCodes) {
        log.info("批量根据parentCode获取所有下级入参:parentCodes:{}", parentCodes);
        Response<List<AreaDTO>> response = baseDataRemote.batchSearchByParentCode(parentCodes);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }


    /**
     * 处理除门店其余层级的返回值
     */
    public List<SalesPlanSelectDTO> dealOtherLevel(List<SalesPlanSelectDTO> leafCodeList, List<String> paramList) {
        List<AreaDTO> areaDTOS = this.batchSearchByParentCode(paramList);
        if (ObjectUtil.isNotEmpty(areaDTOS)) {
            areaDTOS.forEach(item -> {
                SalesPlanSelectDTO selectDTO = new SalesPlanSelectDTO();
                selectDTO.setCode(item.getCode());
                selectDTO.setLevel(item.getLevel());
                leafCodeList.add(selectDTO);
            });
        }
        return leafCodeList.stream().distinct().collect(Collectors.toList());
    }

    /**
     * 批量根据区域获取区域下所有门店
     *
     * @param codeList
     * @param level
     * @param pageNum
     * @param pageSize
     * @return
     */
    public List<StoreDTO> ListStoreByArea(List<String> codeList, Integer level, Integer pageNum, Integer pageSize) {
        log.info("批量根据区域获取区域下所有门店入参:parentCodes:{},level:{},pageNum:{},pageSize:{}", codeList, level, pageNum, pageSize);
        if (level.equals(CommonConstants.AREA_LEVEL_ONE)) {
            Response<PageInfo<StoreDTO>> response = baseDataRemote.listStoreByProvince(codeList, pageNum, pageSize);
            if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
                throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
            }
            return response.getData().getList();
        }
        if (level.equals(CommonConstants.AREA_LEVEL_TWO)) {
            Response<PageInfo<StoreDTO>> response = baseDataRemote.listStoreByCity(codeList, pageNum, pageSize);
            if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
                throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
            }
            return response.getData().getList();
        }
        if (level.equals(CommonConstants.AREA_LEVEL_THREE)) {
            Response<PageInfo<StoreDTO>> response = baseDataRemote.listStoreByCounty(codeList, pageNum, pageSize);
            if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
                throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
            }
            return response.getData().getList();
        }
        return null;
    }

    public PageInfo<StoreDTO> listStoreByProvince(List<String> provinceCodeList, Integer pageNum, Integer pageSize) {
        log.info("批量根据省code查询门店入参:provinceCodeList:{}", JSON.toJSONString(provinceCodeList), pageNum, pageSize);
        Response<PageInfo<StoreDTO>> response = baseDataRemote.listStoreByProvince(provinceCodeList, pageNum, pageSize);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }

    public PageInfo<StoreDTO> listStoreByCity(List<String> cityCodeList, Integer pageNum, Integer pageSize) {
        log.info("批量根据市code查询门店入参:provinceCodeList:{}", JSON.toJSONString(cityCodeList), pageNum, pageSize);
        Response<PageInfo<StoreDTO>> response = baseDataRemote.listStoreByCity(cityCodeList, pageNum, pageSize);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }

    public PageInfo<StoreDTO> listStore(StoreDTO storeSimpleParamDTO) {
        log.info("根据门店的信息查询门店入参:storeSimpleParamDTO:{}", storeSimpleParamDTO);
        Response<PageInfo<StoreDTO>> response = baseDataRemote.listStore(storeSimpleParamDTO, 1, 9999);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }

    public PageInfo<StoreInfoDTO> listStoreInfo(StoreDTO storeSimpleParamDTO) {
        log.info("根据门店的信息查询门店入参:storeSimpleParamDTO:{}", storeSimpleParamDTO);
        Response<PageInfo<StoreInfoDTO>> response = baseDataRemote.listStoreInfo(storeSimpleParamDTO, 1, 9999);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }

    public List<KpChannelSystemChannelDTO> queryByKpChannels(List<String> channels) {
        log.info("根据鲲鹏渠道查询对应的中台渠道入参:channels:{}", JSON.toJSONString(channels));
        Response<List<KpChannelSystemChannelDTO>> response = baseDataRemote.queryByKpChannels(channels);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }

    public List<ChannelInfoDTO> queryByParentChannels(List<String> parentChannels) {
        log.info("根据父渠道批量查询子渠道入参:parentChannels:{}", JSON.toJSONString(parentChannels));
        Response<List<ChannelInfoDTO>> response = baseDataRemote.queryByParentChannels(parentChannels);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }

    public List<ChannelDTO> searchByCodeAndType(String channelType, String code, String merchantId, Integer type) {
        log.info("根据门店查询对应的渠道", channelType, code, merchantId, type);
        Response<List<ChannelDTO>> response = baseDataRemote.searchByCodeAndType(channelType, code, merchantId, type);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }

    /**
     * 根据地区编码获取地区层级信息
     *
     * @param areaList
     * @return
     */
    public List<AreaLevelDTO> listRelationByArea(List<String> areaList) {
        log.info("根据地区编码获取地区层级信息入参:areaList:{}", JSON.toJSONString(areaList));
        Response<List<AreaLevelDTO>> response = baseDataRemote.listRelationByArea(areaList);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }

    /**
     * 获取所有直营门店信息
     *
     * @param
     * @return {@link List<StoreInfoDTO>}
     **/
    public List<StoreInfoDTO> listDirectStores() {
        StoreDTO storeDTO1 = new StoreDTO();
        storeDTO1.setStoreProperties("1");
        StoreDTO storeDTO2 = new StoreDTO();
        storeDTO2.setStoreProperties("2");
        StoreDTO storeDTO3 = new StoreDTO();
        storeDTO3.setStoreProperties("4");
        Response<List<StoreInfoDTO>> response1 = baseDataRemote.listDirectStoreInfo(storeDTO1);
        if (!response1.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        List<StoreInfoDTO> storeInfoDTOS = response1.getData();
        Response<List<StoreInfoDTO>> response2 = baseDataRemote.listDirectStoreInfo(storeDTO2);
        if (!response2.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        Response<List<StoreInfoDTO>> response3 = baseDataRemote.listDirectStoreInfo(storeDTO3);
        if (!response3.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        storeInfoDTOS.addAll(response2.getData());
        storeInfoDTOS.addAll(response3.getData());
        return storeInfoDTOS;
    }

    public List<StoreDTO> selectStoreListByCodes(List<String> codeList) {
        log.info("根据地区编码获取地区层级信息入参:codeList:{}", JSON.toJSONString(codeList));
        Response<List<StoreDTO>> response = baseDataRemote.selectStoreListByCodes(codeList);
        if(!response.getCode().equals(ResponseMsg.SUCCESS.getCode())){
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }

    public List<StoreDTO> searchByCodeList(List<String> codeList) {
        log.info("根据地区编码获取地区层级信息入参:codeList:{}", JSON.toJSONString(codeList));
        Response<List<StoreDTO>> response = baseDataRemote.searchByCodeList(codeList);
        if(!response.getCode().equals(ResponseMsg.SUCCESS.getCode())){
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }

    public List<ChannelDTO> getChannelByLevel(Integer level) {
        log.info("根据渠道的等级查询渠道入参:level:{}", level);
        Response<List<ChannelDTO>> response = baseDataRemote.getChannelByLevel(level);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }

    /**
     * 分页查询渠道
     * @param channelInfoDTO
     * @return
     */
    public PageInfo<ChannelDTO> getChannelPage(@RequestBody ChannelInfoDTO channelInfoDTO) {
        Response<PageInfo<ChannelDTO>> response = baseDataRemote.getChannelPage(channelInfoDTO);
        if (!response.getCode().equals(ResponseMsg.SUCCESS.getCode())) {
            throw new RomeException(ResponseMsg.EXCEPTION_2005.getCode(), ResponseMsg.EXCEPTION_2005.getMsg());
        }
        return response.getData();
    }
}
